--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Commit 099c770288e43153be6300adef2d6622db7831b0
Parents : a59b20c
Author : Ivan <ivan@quad4.io>
Signature : Signature validation error
Date : 2026-04-13T17:35:56-05:00
feat(message_handler, nomadnet_downloader, announces, messages): enhance message handling with new contact name, add stale link eviction, and optimize announce upsert logic
Changes
4 files changed, 42 insertions(+), 5 deletions(-)
Diff
diff --git a/meshchatx/src/backend/database/announces.py b/meshchatx/src/backend/database/announces.py
index cf01a3e7..e896d90d 100644
--- a/meshchatx/src/backend/database/announces.py
+++ b/meshchatx/src/backend/database/announces.py
@@ -8,7 +8,6 @@ class AnnounceDAO:
self.provider = provider
def upsert_announce(self, data):
- # Ensure data is a dict if it's a sqlite3.Row
if not isinstance(data, dict):
data = dict(data)
@@ -22,12 +21,20 @@ class AnnounceDAO:
"snr",
"quality",
]
- # These are safe as they are from a hardcoded list
columns = ", ".join(fields)
placeholders = ", ".join(["?"] * len(fields))
- update_set = ", ".join(
- [f"{f} = EXCLUDED.{f}" for f in fields if f != "destination_hash"],
- )
+
+ update_parts = []
+ for f in fields:
+ if f == "destination_hash":
+ continue
+ if f == "app_data":
+ update_parts.append(
+ "app_data = COALESCE(EXCLUDED.app_data, announces.app_data)",
+ )
+ else:
+ update_parts.append(f"{f} = EXCLUDED.{f}")
+ update_set = ", ".join(update_parts)
query = (
f"INSERT INTO announces ({columns}, created_at, updated_at) VALUES ({placeholders}, ?, ?) " # noqa: S608
diff --git a/meshchatx/src/backend/database/messages.py b/meshchatx/src/backend/database/messages.py
index af21db3e..792eb4bb 100644
--- a/meshchatx/src/backend/database/messages.py
+++ b/meshchatx/src/backend/database/messages.py
@@ -59,6 +59,24 @@ class MessageDAO:
self.provider.execute(query, params)
+ def update_lxmf_message_state(self, message_hash, state, progress,
+ delivery_attempts, next_delivery_attempt_at,
+ rssi=None, snr=None, quality=None):
+ """Lightweight update for delivery-state changes only.
+
+ Avoids re-serializing the full message (including base64 attachment
+ data) which the heavy ``upsert_lxmf_message`` path does.
+ """
+ now = datetime.now(UTC).isoformat()
+ self.provider.execute(
+ "UPDATE lxmf_messages SET state = ?, progress = ?, "
+ "delivery_attempts = ?, next_delivery_attempt_at = ?, "
+ "rssi = ?, snr = ?, quality = ?, updated_at = ? "
+ "WHERE hash = ?",
+ (state, progress, delivery_attempts, next_delivery_attempt_at,
+ rssi, snr, quality, now, message_hash),
+ )
+
def get_lxmf_message_by_hash(self, message_hash):
return self.provider.fetchone(
"SELECT * FROM lxmf_messages WHERE hash = ?",
diff --git a/meshchatx/src/backend/message_handler.py b/meshchatx/src/backend/message_handler.py
index 93398cd0..486a5d68 100644
--- a/meshchatx/src/backend/message_handler.py
+++ b/meshchatx/src/backend/message_handler.py
@@ -90,6 +90,7 @@ class MessageHandler:
a.app_data as peer_app_data,
c.display_name as custom_display_name,
con.custom_image as contact_image,
+ con.name as contact_name,
i.icon_name, i.foreground_colour, i.background_colour,
r.last_read_at,
f.id as folder_id,
diff --git a/meshchatx/src/backend/nomadnet_downloader.py b/meshchatx/src/backend/nomadnet_downloader.py
index ce725274..d0528240 100644
--- a/meshchatx/src/backend/nomadnet_downloader.py
+++ b/meshchatx/src/backend/nomadnet_downloader.py
@@ -31,6 +31,17 @@ def get_cached_active_link(destination_hash: bytes):
return None
+def sweep_stale_links():
+ """Evict all non-ACTIVE links from the global cache."""
+ with _nomadnet_links_lock:
+ stale = [
+ k for k, v in nomadnet_cached_links.items()
+ if v.status is not RNS.Link.ACTIVE
+ ]
+ for k in stale:
+ del nomadnet_cached_links[k]
+
+
def _cache_link_if_active(destination_hash: bytes, link) -> None:
if link is None or link.status is not RNS.Link.ACTIVE:
return
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────